import configparser
import os
import traceback
from queue import Queue
from threading import Thread

# 创建一个有4个线程的线程池
import sys
import time

import utils
from college.zjwl.zjwlshushengbook import ShuShengParse


class ThreadPoolManger(object):
    """
    线程池管理器
    """

    def __init__(self, thread_num):
        self.work_queue = Queue()
        self.result_queue = Queue()
        self.threadpool = []
        self.thread_num = thread_num
        self.__init_threading_pool(self.thread_num)

    def __init_threading_pool(self, thread_num):
        """
        初始化线程池，创建指定数量的线程池
        :param thread_num: 
        :return: 
        """
        for i in range(int(thread_num)):
            thread = ThreadManager(self.work_queue,self.result_queue)
            thread.setName("thread_{0}".format(i + 1))
            self.threadpool.append(thread)

    def add_thread(self, thread_num):
        """
        添加线程，thread_num是添加线程的数量
        :param thread_num: 
        :return: 
        """
        for i in range(thread_num):
            thread = ThreadManager(self.work_queue,self.result_queue)
            thread.setName("thread_%s".format(self.thread_num + i + 1))
            thread.start()
            self.threadpool.append(thread)
        self.thread_num = self.thread_num + thread_num

    def delete_thread(self, thread_num):
        """
        删除多少个线程，thread_num为删除数量
        :param thread_num: 
        :return: 
        """
        try:
            for i in range(thread_num):
                self.threadpool = self.threadpool.pop()
        except IndexError:
            self.thread_num = 0
        else:
            self.thread_num = self.thread_num - thread_num

    def set_thread_num(self, thread_num):
        """
        设置当前线程数量
        :return: 
        """
        if thread_num > self.thread_num:
            self.add_thread(thread_num - self.thread_num)
        else:
            self.threadpool = self.threadpool[:int(thread_num)]
        self.thread_num = thread_num

    def add_job(self, func, *args, **kwargs):
        """
        将任务放入队列，等待线程池阻塞读取，参数是被执行的函数和函数的参数
        :param func: 
        :param args: 
        :param kwargs: 
        :return: 
        """
        self.work_queue.put((func, self.result_queue,args, kwargs))

    def start(self):
        for thread in self.threadpool:
            time.sleep(2)
            thread.start()


class ThreadManager(Thread):
    """
    定义线程类，继承threading.Thread
    """

    def __init__(self, work_queue, result_queue):
        Thread.__init__(self)
        self.work_queue = work_queue
        self.result_queue = result_queue
        self.daemon = True  ## 主线程退出  该线程也会退出

    def run(self):
        """
        启动线程
        :return: 
        """
        while True:
            try:
                target,result_queue, args, kwargs = self.work_queue.get()
                target(result_queue,*args, **kwargs)
                self.work_queue.task_done()
            except UnicodeDecodeError as e:
                print(e)


# if __name__ == "__main__":
#     cf = configparser.ConfigParser()
#     try:
#         curPath = os.path.dirname(os.path.abspath(__file__))
#         cf.read(os.path.join(curPath, 'config.ini'))
#     except:
#         print('读取配置失败:' + traceback.format_exc())
#         sys.exit(-1)
#     if cf:
#         thread_num = cf.get('thread', 'threadnum')
#         thread_pool = ThreadPoolManger(thread_num)
#         down = ShuShengDownload()
#         func = down.down_list_run
#         for i in range(1, 20389):
#             thread_pool.add_job(func, i)
#         thread_pool.start()
#         while True:
#             pass


# cf = configparser.ConfigParser()
# try:
#     curPath = os.path.dirname(os.path.abspath(__file__))
#     cf.read(os.path.join(curPath, 'config.ini'))
# except:
#     print('读取配置失败:' + traceback.format_exc())
#     sys.exit(-1)
# if cf:
#     thread_num = cf.get('thread', 'threadnum')
#     if thread_num:
#         if thread_pool or 'thread_num' in locals():
#             number = thread_pool.set_thread_num(thread_num)
#         else:
#             thread_pool = ThreadPoolManger(thread_num)


if __name__ == "__main__":
    cf = configparser.ConfigParser()
    try:
        curPath = os.path.dirname(os.path.abspath(__file__))
        cf.read(os.path.join(curPath, 'config.ini'))
    except:
        print('读取配置失败:' + traceback.format_exc())
        sys.exit(-1)
    if cf:
        thread_num = cf.get('thread', 'threadnum')
        thread_pool = ThreadPoolManger(thread_num)
        # down = ShuShengDownload()
        # func = down.down_cover_run
        # conn = utils.init_db('mysql', 'zjwl')
        # cur = conn.cursor()
        parser = ShuShengParse()
        func = parser.parse_detail_run
        conn = utils.init_db('sqlite3', parser.template_file)
        print("开始查询")
        # cur.execute("select bookid,cover from shusheng where cover_stat=0")
        # rows = cur.fetchall()
        # count = len(rows)
        # print(count)
        print("开始添加工作")
        count = 0
        for file, fullpath in utils.file_list(parser.detail_path):
            count += 1
            thread_pool.add_job(func, file, fullpath)
            if count > 1500:
                break
        thread_pool.start()
        # for bookid, cover in rows:
        #     print(bookid)
        #     thread_pool.add_job(func, bookid, cover)
        #     count -= 1
        # thread_pool.start()
        print("添加工作完毕")
        # while True:
        #     if not thread_pool.result_queue.empty():
        #         sql = thread_pool.result_queue.get()
        #         print(sql)
        #         cur.execute(sql)
        #         conn.commit()
        #         thread_pool.result_queue.task_done()
        results = []
        stmt = (
            '''insert or ignore into modify_title_info_zt(lngid,rawid,title,creator,description,date,date_created,
            language,country,provider,provider_url,provider_id,type,cover,medium,batch,publisher,identifier_pisbn,title_series,folio_size)  VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?);'''
        )
        cnt = 0
        while True:
            if not thread_pool.result_queue.empty():
                result = thread_pool.result_queue.get()
                results.append(result)
                thread_pool.result_queue.task_done()
                if utils.parse_results_to_sql(conn, stmt, results, 1000):
                    cnt += 1001
                    utils.printf("已经解析大约 ", cnt, ' 条数据...,all data ',count)
                    results.clear()
                if thread_pool.result_queue.empty():
                    print("结果线程已空")
                    time.sleep(10)
                    t1 = thread_pool.result_queue.empty()
                    time.sleep(10)
                    t2 = thread_pool.result_queue.empty()
                    if t1 and t2:
                        print("判断为最后的数据")
                        cnt += len(results)
                        utils.printf("已经解析大约 ", cnt, ' 条数据...,all data ', count)
                        utils.parse_results_to_sql(conn, stmt, results)
                        results.clear()
                        conn.close()
            else:
                time.sleep(30)

